﻿using System;
using System.Collections;
using System.Collections.ObjectModel;
using System.Configuration;
using System.Globalization;
using System.Reflection;
using System.Security;
using System.Text;
using System.Xml;

 
namespace CARMSBusiness
{
    public class TaskSectionHandler : IConfigurationSectionHandler
    {
        private const string NAME_ATTR = "name";
        private const string INTERVAL_ATTR = "interval";
        private const string ENABLED_ATTR = "enabled";
        private const string PRIORITY_ATTR = "priority";
        private const string TYPE_ATTR = "type";
        internal static bool ToBoolean(string argValue, bool defaultValue)
        {
            if (!string.IsNullOrEmpty(argValue))
            {
                try
                {
                    return bool.Parse(argValue);
                }
                catch (Exception exception)
                {
                    throw new ConfigurationErrorsException("[" + argValue + "] is not in proper bool form.", exception);
                }
            }
            return defaultValue;
        }

        private static Type GetTypeFromString(Assembly relativeAssembly, string typeName, bool throwOnError, bool ignoreCase)
        {
            if (typeName.IndexOf(',') == -1)
            {
                Type type = relativeAssembly.GetType(typeName, false, ignoreCase);
                if (type != null)
                {
                    return type;
                }
                Assembly[] assemblies = null;
                try
                {
                    assemblies = AppDomain.CurrentDomain.GetAssemblies();
                }
                catch (SecurityException)
                {
                }
                if (assemblies != null)
                {
                    foreach (Assembly assembly in assemblies)
                    {
                        type = assembly.GetType(typeName, false, ignoreCase);
                        if (type != null)
                        {
                            return type;
                        }
                    }
                }
                if (throwOnError)
                {
                    throw new TypeLoadException("Could not load type [" + typeName + "]. Tried assembly [" + relativeAssembly.FullName + "] and all loaded assemblies");
                }
                return null;
            }
            return Type.GetType(typeName, throwOnError, ignoreCase);
        }

        internal static Type GetTypeFromString(string typeName, bool throwOnError, bool ignoreCase)
        {
            return GetTypeFromString(Assembly.GetCallingAssembly(), typeName, throwOnError, ignoreCase);
        }

        public object Create(object parent, object configContext, XmlNode section)
        {
            TaskCollection value;
            if (parent == null)
            {
                value = new TaskCollection();
            }
            else
            {
                value = (TaskCollection)parent;
            }
            foreach (XmlNode childNode in section.ChildNodes)
            {
                if (childNode.NodeType != XmlNodeType.Comment)
                {
                    childNode.CheckForNonElement();
                }
                string name = childNode.RemoveRequiredAttribute(NAME_ATTR);
                bool enabled = ToBoolean(childNode.RemoveAttribute(ENABLED_ATTR), true);
                string typeName = childNode.RemoveRequiredAttribute(TYPE_ATTR);
                string priorityName = childNode.RemoveAttribute(PRIORITY_ATTR);
                var priority = string.IsNullOrEmpty(priorityName)
                                   ? Priority.Medium
                                   : (Priority)Enum.Parse(typeof(Priority), priorityName, true);
                double interval = double.Parse(childNode.RemoveRequiredAttribute(INTERVAL_ATTR));
                childNode.CheckForUnrecognizedAttributes();
                value.Add(new TaskConfiguration
                {
                    Name = name,
                    Interval = interval,
                    TaskType = GetTypeFromString(typeName, true, true),
                    Enabled = enabled,
                    Priority = priority,
                    ConfigurationNode = childNode
                });
            }
            return value;
        }
    

    }

   
}
